<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .box{position: relative;margin: 30px;}
    .box .middleBox{position: relative;width: 350px;height: 350px;}
    .box .middleBox span{position: absolute;background: rgba(200,0,0,0.6);left:0;top:0;display:none}
    .box .largeBox{width: 350px;height: 350px;position: absolute;left: 400px;top:0;overflow: hidden;display: none;}
    .box .largeBox img{position: absolute;left:0;top:0;}

    .smallBox{width:350px;position:relative;overflow: hidden;height:52px;margin: 10px 0;}
    .smallBox ul{width: 540px;margin:0;padding:0;list-style:none;position: absolute;}
    .smallBox li{float: left;margin:0 4px;border:solid 1px transparent;}
    .smallBox li img{display:block;}
    .smallBox li:first-child{margin-left:0;}
    .smallBox li:last-child{margin-right:0;}
    .smallBox input{width:20px;height:50px;margin:0;padding:0;border:none;position:absolute;top:1px;background:rgba(200,200,200,0.4);z-index:1}
    .smallBox input:hover{background:rgba(200,200,200,0.8)}
    .smallBox .left{left:0}
    .smallBox .right{right:0}
  </style>
</head>
<body>
  <div class="box">
    <div class="middleBox">
      <img src="./imgs/m0.jpg" alt="">
      <span></span>
    </div>
    <div class="smallBox">
      <input type="button" value="<" class="left">
      <input type="button" value=">" class="right">
      <ul>
        <li><img src="./imgs/s0.jpg" alt=""></li>
        <li><img src="./imgs/s1.jpg" alt=""></li>
        <li><img src="./imgs/s2.jpg" alt=""></li>
        <li><img src="./imgs/s0.jpg" alt=""></li>
        <li><img src="./imgs/s1.jpg" alt=""></li>
        <li><img src="./imgs/s2.jpg" alt=""></li>
        <li><img src="./imgs/s0.jpg" alt=""></li>
        <li><img src="./imgs/s1.jpg" alt=""></li>
        <li><img src="./imgs/s2.jpg" alt=""></li>
      </ul>
    </div>
    <div class="largeBox">
      <img src="./imgs/l0.jpg" alt="">
    </div>
  </div>
</body>
<script>
  function Magnifier({mBox, span, lBox, lBimg, sBox, left, right, sImgs, index=0, mBimg}){
    this.mBox = mBox;
    this.span = span;
    this.lBox = lBox;
    this.lBimg = lBimg;
    this.mBimg = mBimg;
    // 0. 接收参数获取元素，获取默认显示图片索引
    this.sBox = sBox;
    this.left = left;
    this.right = right;
    this.sImgs = sImgs;
    this.index = index;
    // 1. 绑定事件
    this.addEvent();
  }
  Magnifier.prototype.addEvent = function(){
    const that = this;
    this.mBox.onmouseover = function(){
      that.show();
      that.init();
    }
    this.mBox.onmouseout = function(){
      that.hide()
    }
    this.mBox.onmousemove = function(eve){
      const e = eve || window.event;
      that.move(e);
    }
    // 2. 具体的事件绑定
    for(let i=0;i<this.sImgs.length;i++){
      this.sImgs[i].index = i;
      this.sImgs[i].onclick = function(){
        // 3. 设置高亮样式
        that.setActive(this.index);
        // 4. 根据点击的图片修改中图和大图
        that.changeImg(this.index);
      }
    }
    // 6. 计算初始已经显示的图片数量
    this.pageIndex = parseInt(350 / (this.sImgs[0].offsetWidth + 8));
    this.nowIndex = this.pageIndex;
    // 5. 分页器的左右按钮绑定事件
    this.left.onclick = function(){
      // 6-1. 计算索引
      if(that.nowIndex !== that.pageIndex){
        that.nowIndex--;
      }
      // 7-1. 根据索引切换图片
      that.moveImg();
    }
    this.right.onclick = function(){
      // 6-2. 计算索引
      if(that.nowIndex !== that.sImgs.length-1){
        that.nowIndex++;
      }
      // 7-2. 根据索引切换图片
      that.moveImg();
    }
  }
  Magnifier.prototype.moveImg = function(){
    this.sBox.style.left = -(this.nowIndex - this.pageIndex) * (this.sImgs[0].offsetWidth + 8) + "px";
  }
  Magnifier.prototype.changeImg = function(now){
    this.mBimg.src = `./imgs/m${now}.jpg`;
    this.lBimg.src = `./imgs/l${now}.jpg`;
  }
  Magnifier.prototype.setActive = function(now){
    // 清除上一个（默认索引）元素的样式
    this.sImgs[this.index].style.borderColor = "transparent";
    // 给当前点击元素添加样式
    this.sImgs[now].style.borderColor = "blue";
    // 将当前点击元素的索引设置给默认索引
    this.index = now;
  }
  Magnifier.prototype.show = function(){
    this.span.style.display = "block";
    this.lBox.style.display = "block";
  }
  Magnifier.prototype.hide = function(){
    this.span.style.display = "none";
    this.lBox.style.display = "none";
  }
  Magnifier.prototype.move = function(e){
    let l = e.pageX - this.mBox.offsetLeft - this.mBox.offsetParent.offsetLeft - this.span.offsetWidth/2;
    let t = e.pageY - this.mBox.offsetTop - this.mBox.offsetParent.offsetTop - this.span.offsetHeight/2;
    if(l < 0) l = 0;
    if(t < 0) t = 0;
    if( l > this.mBw - this.span.offsetWidth ){
      l = this.mBw - this.span.offsetWidth;
    }
    if( t > this.mBh - this.span.offsetHeight ){
      t = this.mBh - this.span.offsetHeight;
    }
    this.span.style.left = l + "px";
    this.span.style.top = t + "px";
    const x = l / (this.mBw - this.span.offsetWidth);
    const y = t / (this.mBh - this.span.offsetHeight);
    this.lBimg.style.left = -x * ( this.lBimgW - this.lBw ) + "px";
    this.lBimg.style.top = -y * ( this.lBimgH - this.lBh ) + "px";
  }
  Magnifier.prototype.init = function(){
    this.lBw = this.lBox.offsetWidth;
    this.lBh = this.lBox.offsetHeight;
    this.lBimgW = this.lBimg.offsetWidth;
    this.lBimgH = this.lBimg.offsetHeight;
    this.mBw = this.mBox.offsetWidth;
    this.mBh = this.mBox.offsetHeight;

    const x = this.lBw / this.lBimgW;
    const y = this.lBh / this.lBimgH;
    this.span.style.width = x * this.mBw + "px";
    this.span.style.height = y * this.mBh + "px";
  }

  onload = function(){
    new Magnifier({
      mBox: $(".middleBox"),
      span: $(".middleBox span"),
      lBox: $(".largeBox"),
      lBimg: $(".largeBox img"),
      mBimg: $(".middleBox img"),
      sBox: $(".smallBox ul"),
      left: $(".left"),
      right: $(".right"),
      sImgs: $(".smallBox ul").children
    });
  }






  function $(select){
    return document.querySelector(select)
  }

</script>
</html>